package org.zookeeper.examples.command.overview;

import static org.apache.zookeeper.CreateMode.PERSISTENT;

import java.io.IOException;
import java.util.Arrays;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;

/**
 * zookeeper 创建\删除\查询\修改 示例
 *
 * @author slydm
 */
public class CRUDDemo {

  public static void main(String[] args) throws IOException, KeeperException, InterruptedException {

    ZooKeeper zooKeeper = new ZooKeeper("localhost:2181", 3000, watchedEvent -> {
      System.out.println(watchedEvent);
    });
    String path = "/b";
    byte[] data = "I'm /b node".getBytes();
    createPersistentNode(zooKeeper, path, data);

    byte[] returnData = getData(zooKeeper, path);
    System.out.println("查询到节点'" + path + "' 数据: " + new String(returnData));
    System.out.println("查询方法返回的数据与原始数据是否一致? " + Arrays.equals(data, returnData));

    System.out.println("=============更新节点数据=============");
    data = "I'm /b node data".getBytes();
    setNodeData(zooKeeper, path, data);
    returnData = getData(zooKeeper, path);
    System.out.println("查询到节点'" + path + "' 数据: " + new String(returnData));
    System.out.println("查询方法返回的数据与原始数据是否一致? " + Arrays.equals(data, returnData));


  }


  /**
   * 创建持久化znode节点
   *
   * @param zooKeeper zookeeper实例
   * @param path      节点路径
   * @param data      节点数据
   */
  private static void createPersistentNode(ZooKeeper zooKeeper, String path, byte[] data)
      throws KeeperException, InterruptedException {
    // 判断节点是否存在
    if (existsNode(zooKeeper, path)) {
      // 存在,删除节点
      deleteNode(zooKeeper, path);
    }
    zooKeeper.create(path, data, Ids.OPEN_ACL_UNSAFE, PERSISTENT);
  }

  /**
   * 获取znode节点关联的数据
   *
   * @param zooKeeper zookeeper实例
   * @param path      节点路径
   * @return 查询的节点关联的数据
   * @throws KeeperException
   * @throws InterruptedException
   */
  private static byte[] getData(ZooKeeper zooKeeper, String path)
      throws KeeperException, InterruptedException {
    return zooKeeper.getData(path, false, null);
  }

  /**
   * 删除指定节点
   *
   * @param zooKeeper zookeeper实例
   * @param path      节点路径
   * @param version   数据版本
   * @throws KeeperException
   * @throws InterruptedException
   */
  private static void deleteNode(ZooKeeper zooKeeper, String path, int version)
      throws KeeperException, InterruptedException {
    zooKeeper.delete(path, version);
  }

  /**
   * 删除指定节点
   *
   * @param zooKeeper
   * @param path
   * @throws KeeperException
   * @throws InterruptedException
   */
  private static void deleteNode(ZooKeeper zooKeeper, String path)
      throws KeeperException, InterruptedException {
    zooKeeper.delete(path, -1);
  }

  private static void setNodeData(ZooKeeper zooKeeper, String path, byte[] data)
      throws KeeperException, InterruptedException {
    zooKeeper.setData(path, data, -1);
  }

  /**
   * 判断节点是否存在
   *
   * @param zooKeeper zookeeper实例
   * @param path      节点路径
   * @return 存在 true, 否则 false;
   * @throws KeeperException
   * @throws InterruptedException
   */
  private static boolean existsNode(ZooKeeper zooKeeper, String path)
      throws KeeperException, InterruptedException {
    return zooKeeper.exists(path, false) != null;
  }
}
